/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "tim.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
extern motor_control_t motor_control[5];
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
void processMotorTask(uint8_t index);
/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
osThreadId ledTaskHandle;
osThreadId M1TASKHandle;
osThreadId M2TASKHandle;
osThreadId M3TASKHandle;
osThreadId M4TASKHandle;
osThreadId M5TASKHandle;
osSemaphoreId M1_SemapHandle;
osSemaphoreId M2_SemapHandle;
osSemaphoreId M3_SemapHandle;
osSemaphoreId M4_SemapHandle;
osSemaphoreId M5_SemapHandle;
osSemaphoreId* arry_semapHandle[5];
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void led_Task(void const * argument);
void M1_Task(void const * argument);
void M2_TASK(void const * argument);
void M3_TASK(void const * argument);
void M4_TASK(void const * argument);
void M5_TASK(void const * argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/* GetIdleTaskMemory prototype (linked to static allocation support) */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );

/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
static StaticTask_t xIdleTaskTCBBuffer;
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];

void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
  *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
  *ppxIdleTaskStackBuffer = &xIdleStack[0];
  *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
  /* place for user code */
}
/* USER CODE END GET_IDLE_TASK_MEMORY */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* Create the semaphores(s) */
  /* definition and creation of M1_Semap */
  osSemaphoreDef(M1_Semap);
  M1_SemapHandle = osSemaphoreCreate(osSemaphore(M1_Semap), 1);

  /* definition and creation of M2_Semap */
  osSemaphoreDef(M2_Semap);
  M2_SemapHandle = osSemaphoreCreate(osSemaphore(M2_Semap), 1);

  /* definition and creation of M3_Semap */
  osSemaphoreDef(M3_Semap);
  M3_SemapHandle = osSemaphoreCreate(osSemaphore(M3_Semap), 1);

  /* definition and creation of M4_Semap */
  osSemaphoreDef(M4_Semap);
  M4_SemapHandle = osSemaphoreCreate(osSemaphore(M4_Semap), 1);

  /* definition and creation of M5_Semap */
  osSemaphoreDef(M5_Semap);
  M5_SemapHandle = osSemaphoreCreate(osSemaphore(M5_Semap), 1);

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
	

		arry_semapHandle[0]=&M1_SemapHandle;
		arry_semapHandle[1]=&M2_SemapHandle;
		arry_semapHandle[2]=&M3_SemapHandle;
		arry_semapHandle[3]=&M4_SemapHandle;
		arry_semapHandle[4]=&M5_SemapHandle;

for(int i=0;i<5;i++)
{
	 xSemaphoreTake(*arry_semapHandle[i],
                              portMAX_DELAY); 
}
	
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* definition and creation of ledTask */
  osThreadDef(ledTask, led_Task, osPriorityNormal, 0, 128);
  ledTaskHandle = osThreadCreate(osThread(ledTask), NULL);

  /* definition and creation of M1TASK */
  osThreadDef(M1TASK, M1_Task, osPriorityIdle, 0, 128);
  M1TASKHandle = osThreadCreate(osThread(M1TASK), NULL);

  /* definition and creation of M2TASK */
  osThreadDef(M2TASK, M2_TASK, osPriorityIdle, 0, 128);
  M2TASKHandle = osThreadCreate(osThread(M2TASK), NULL);

  /* definition and creation of M3TASK */
  osThreadDef(M3TASK, M3_TASK, osPriorityIdle, 0, 128);
  M3TASKHandle = osThreadCreate(osThread(M3TASK), NULL);

  /* definition and creation of M4TASK */
  osThreadDef(M4TASK, M4_TASK, osPriorityIdle, 0, 128);
  M4TASKHandle = osThreadCreate(osThread(M4TASK), NULL);

  /* definition and creation of M5TASK */
  osThreadDef(M5TASK, M5_TASK, osPriorityIdle, 0, 128);
  M5TASKHandle = osThreadCreate(osThread(M5TASK), NULL);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

}

/* USER CODE BEGIN Header_led_Task */
/**
  * @brief  Function implementing the ledTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_led_Task */
__weak void led_Task(void const * argument)
{
  /* USER CODE BEGIN led_Task */
  /* Infinite loop */
  for(;;)
  {
		HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
    osDelay(1000);
  }
  /* USER CODE END led_Task */
}

/* USER CODE BEGIN Header_M1_Task */
/**
* @brief Function implementing the M1TASK thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_M1_Task */
__weak void M1_Task(void const * argument)
{
  /* USER CODE BEGIN M1_Task */

  /* Infinite loop */
  for(;;)
  {
		
		BaseType_t xReturn = xSemaphoreTake(M1_SemapHandle,
                              portMAX_DELAY); 

		processMotorTask(0);
    
  }
  /* USER CODE END M1_Task */
}

/* USER CODE BEGIN Header_M2_TASK */
/**
* @brief Function implementing the M2TASK thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_M2_TASK */
__weak void M2_TASK(void const * argument)
{
  /* USER CODE BEGIN M2_TASK */

  /* Infinite loop */
  for(;;)
  {
    BaseType_t xReturn = xSemaphoreTake(M2_SemapHandle,
                              portMAX_DELAY); 
		processMotorTask(1);
  }
  /* USER CODE END M2_TASK */
}

/* USER CODE BEGIN Header_M3_TASK */
/**
* @brief Function implementing the M3TASK thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_M3_TASK */
__weak void M3_TASK(void const * argument)
{
  /* USER CODE BEGIN M3_TASK */

  /* Infinite loop */
  for(;;)
  {
    BaseType_t xReturn = xSemaphoreTake(M3_SemapHandle,
                              portMAX_DELAY); 
		processMotorTask(2);
  }
  /* USER CODE END M3_TASK */
}

/* USER CODE BEGIN Header_M4_TASK */
/**
* @brief Function implementing the M4TASK thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_M4_TASK */
__weak void M4_TASK(void const * argument)
{
  /* USER CODE BEGIN M4_TASK */

  /* Infinite loop */
  for(;;)
  {
   BaseType_t xReturn = xSemaphoreTake(M4_SemapHandle,
                              portMAX_DELAY); 
		processMotorTask(3);
  }
  /* USER CODE END M4_TASK */
}

/* USER CODE BEGIN Header_M5_TASK */
/**
* @brief Function implementing the M5TASK thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_M5_TASK */
__weak void M5_TASK(void const * argument)
{
  /* USER CODE BEGIN M5_TASK */
  /* Infinite loop */
  for(;;)
  {
   BaseType_t xReturn = xSemaphoreTake(M5_SemapHandle,
                             portMAX_DELAY); 
	 processMotorTask(4);
  }
  /* USER CODE END M5_TASK */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
void processMotorTask(uint8_t index)
{
	  motor_control[index].motor_state=busy;
		printf("M%d is moving\r\n",index+1);
		setMotorSpeed(index,motor_control[index].speed);
		vTaskDelay(motor_control[index].exp_move_time);
	  setMotorSpeed(index,0);
		motor_control[index].motor_state=ready;
		printf("M%d is finish\r\n",index+1);
}


/* USER CODE END Application */
